package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.constant.App;
import cn.huiyunche.base.service.enums.CompanyTypeEnum;
import cn.huiyunche.base.service.enums.UserTypeEnum;
import cn.huiyunche.base.service.framework.utils.HYCUtils;
import cn.huiyunche.base.service.framework.utils.Md5PasswordEncoderUtils;
import cn.huiyunche.base.service.interfaces.*;
import cn.huiyunche.base.service.mappers.*;
import cn.huiyunche.base.service.mappers.ext.CarrierManpper;
import cn.huiyunche.base.service.mappers.ext.CompanyUserManpper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.vo.*;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.lang.Collections;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
public class CompanyServiceImpl implements CompanyService {

    private static final Logger LOGGER = LoggerFactory.getLogger(CompanyServiceImpl.class);

    @Autowired
    private BCompanyMapper bCompanyMapper = null;

    @Autowired
    private SUserInviteMapper sUserInviteMapper = null;

    @Autowired
    private SUserMapper sUserMapper = null;

    @Autowired
    private BAreaMapper bAreaMapper = null;

    @Autowired
    private CompanyUserManpper companyUserManpper = null;

    @Autowired
    private CarrierManpper carrierManpper = null;

    @Autowired
    private BScoresTurnoverService bScoresTurnoverService = null;

    @Autowired
    private BAreaService areaService = null;

    @Autowired
    private UserService userService = null;

    @Autowired
    private CAccntBillService cAccntBillService = null;

    @Autowired
    private BScoresService bScoresService = null;

    @Autowired
    private BCompanyUserMapper bCompanyUserMapper = null;

    @Autowired
    private BCompanyUserService bCompanyUserService;

    private Md5PasswordEncoder md5PasswordEncoder = null;

    private BCompanyMapper getBCompanyMapper() {
        return this.bCompanyMapper;
    }

    private BCompanyUserMapper getBCompanyUserMapper() {
        return this.bCompanyUserMapper;
    }

    private CarrierManpper getCarrierManpper() {
        return this.carrierManpper;
    }

    private BAreaMapper getbAreaMapper() {
        return this.bAreaMapper;
    }

    private SUserInviteMapper getSUserInviteMapper() {
        return this.sUserInviteMapper;
    }

    private SUserMapper getSUserMapper() {
        return this.sUserMapper;
    }

    private CompanyUserManpper getCompanyUserManpper() {
        return this.companyUserManpper;
    }

    private BScoresTurnoverService getBScoresTurnoverService() {
        return this.bScoresTurnoverService;
    }

    private BAreaService getAreaService() {
        return this.areaService;
    }

    private UserService getUserService() {
        return this.userService;
    }

    private CAccntBillService getCAccntBillService() {
        return this.cAccntBillService;
    }

    private BScoresService getBScoresService() {
        return this.bScoresService;
    }

    /**
     * 企业默认密码
     */
    private final String C_COMPANY_USER_DEFAULT_PWD = "123456a"; // "123456a";

    // 查询当前登录用户
    public UserShowVo getUserShowVo() {
        try {
            return this.getUserService().getCurrentUser();
        } catch (Exception e) {
            LOGGER.error("select current user ERROR : {}.", e);
            throw new BusinessException("查询当前登录用户异常");
        }
    }

    /**
     * 查询企业列表
     *
     * @param page
     * @return
     * @throws BusinessException
     */
    @Override
    public Map<String, Object> list(PageVo page) {
        LOGGER.info("list params : {}", page);
        List<BCompany> companyList = new ArrayList<BCompany>();
        BCompanyExample example = new BCompanyExample();

        example.setLimitStart(page.getStartIndex());
        example.setLimitEnd(page.getPageSize());
        if (StringUtils.isNotBlank(page.getOrder())) {
            example.setOrderByClause(page.getOrder());
        } else {
            example.setOrderByClause("id DESC");
        }
        page.setTotalRecord(this.getBCompanyMapper().countByExample(example));
        companyList = this.getBCompanyMapper().selectByExample(example);
        Map<String, Object> map = new HashMap<String, Object>();

        map.put("companyInfo", companyList);
        map.put("page", page);
        return map;
    }

    /**
     * 根据企业ID 查询企业详情
     *
     * @param id
     * @return
     * @throws BusinessException
     */
    @Override
    public Map<String, Object> selectById(Long id) {
        LOGGER.info("selectById param : {}", id);
        Map<String, Object> map = new HashMap<String, Object>();
        BCompany company = this.getBCompanyMapper().selectByPrimaryKey(id);

        // 查询省
        BAreaExample bAreaExample = new BAreaExample();
        bAreaExample.createCriteria().andLevelEqualTo("1");
        List<BArea> proDate = this.getbAreaMapper().selectByExample(bAreaExample);

        map.put("proDate", proDate);
        map.put("companyData", company);
        return map;
    }

    /**
     * 添加公司信息
     * 托运企业
     * 物流企业
     *
     * @param companyData
     * @return
     * @throws BusinessException
     */
    @Override
    public Result<String> saveCompany(BCompany companyData) {
        LOGGER.info("saveCompany param : {}", companyData);
        Result<String> result = new Result<String>(true, "添加公司信息成功");
        try {
            if (companyData.getCompanyCategory() == null) {
                LOGGER.info("companyCateGory is not null");
                throw new BusinessException("公司分类不能为空");
            } else if (StringUtils.isBlank(companyData.getCompanyName())) {
                LOGGER.info("companyName is not null");
                throw new BusinessException("公司名称不能为空");
            }

            BArea proBArea = this.getAreaService().selectAreaByCodeAndLevel(companyData.getProvinceCode(), "1");
            BArea cityBArea = this.getAreaService().selectAreaByCodeAndLevel(companyData.getCityCode(), "2");

            String companyName = companyData.getCompanyName();
            // 去重判断。
            BCompanyExample example = new BCompanyExample();
            example.createCriteria().andCompanyNameEqualTo(companyName).andCompanyCategoryEqualTo(companyData.getCompanyCategory());
            List<BCompany> list = this.getBCompanyMapper().selectByExample(example);
            if (list.size() > 0) {
                result.setSuccess(false);
                result.setMessage("公司信息已存在");
                return result;
            }

            companyData.setProvinceName(proBArea.getName());
            companyData.setCityName(cityBArea.getName());
            if (companyData.getId() != null) {
                companyData.setUpdateTime(new Date());
                int chaConut = this.getBCompanyMapper().updateByPrimaryKeySelective(companyData);
                LOGGER.info("udpate company ：{} 条记录。", chaConut);
            } else {
                companyData.setAdminId(0L);
                companyData.setCompanyCode(123456L);
                companyData.setCreateTime(new Date());
                companyData.setUpdateTime(new Date());

                int insConut = this.getBCompanyMapper().insertSelective(companyData);
                LOGGER.info("新增公司信息：{} 条记录。", insConut);

                Long citycodeSuccess = Long.valueOf(Md5PasswordEncoderUtils.getInvitationCode(companyData.getId() + "", 6));
                // 去重判断。
                BCompanyExample bExample = new BCompanyExample();
                bExample.createCriteria().andCompanyCodeEqualTo(citycodeSuccess);
                List<BCompany> clist = this.getBCompanyMapper().selectByExample(bExample);
                if (clist.size() > 0) {
                    result.setSuccess(false);
                    result.setMessage("生成公司编码已存在");
                    return result;
                }
                companyData.setCompanyCode(citycodeSuccess);
                if (companyData.getCompanyCategory().equals(CompanyTypeEnum.CCOMPANY.getValue())) {
                    Long securitycode = Long.valueOf(Md5PasswordEncoderUtils.getInvitationCode(companyData.getId() + companyData.getCityCode(), 6));
                    companyData.setSecuritycode(securitycode + "");
                }
                int updCount = this.getBCompanyMapper().updateByPrimaryKeySelective(companyData);
                LOGGER.info("更新公司code：{} 条记录。id：{}。", updCount, companyData.getId());
            }
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("update on insert error: {}", e);
        }
        return result;
    }

    @Override
    public Map<String, Object> addCompany() {
        Map<String, Object> map = new HashMap<String, Object>();
        // 查询省
        BAreaExample bAreaExample = new BAreaExample();
        bAreaExample.createCriteria().andLevelEqualTo("1");
        List<BArea> proDate = this.getbAreaMapper().selectByExample(bAreaExample);

        map.put("proDate", proDate);
        return map;
    }

    /**
     * 添加企业用户
     *
     * @param surv
     * @return
     */
    public Result<String> signCommpanyUser(SUserRequestVo surv) {
        LOGGER.info("signCommpanyUser param : {}", surv);
        Result<String> r = new Result<>(true);
        try {
            LOGGER.info("sign commpany user params  surv : {}.", surv);
            int category = surv.getCompanyCategory();

            SUserExample sue = new SUserExample();

            if (category == UserTypeEnum.COMPANY.getValue()) {
                sue.createCriteria().andPhoneEqualTo(surv.getPhone()).andUserTypeEqualTo(UserTypeEnum.COMPANY.getValue());
            } else if (category == UserTypeEnum.SCOMPANY.getValue()) {
                sue.createCriteria().andPhoneEqualTo(surv.getPhone()).andUserTypeEqualTo(UserTypeEnum.SCOMPANY.getValue());
            }
            List<SUser> list = this.getSUserMapper().selectByExample(sue);
            if (list.size() > 0) {
                r.setSuccess(false);
                r.setMessage("用户手机号已注册");
                return r;
            }

            Date d = new Date();
            SUser su = new SUser();
            BeanCopier beanCopierT = BeanCopier.create(SUserRequestVo.class, SUser.class, false);
            beanCopierT.copy(surv, su, null);

            su.setCreateTime(d);
            su.setEnable("T");
            su.setUpdateTime(d);
            su.setUserType(category);
            su.setPwd(this.getmd5PasswordEncoder().encodePassword(C_COMPANY_USER_DEFAULT_PWD,
                    HYCUtils.getConstantPropertiesLoader().getProperty(App.SECURE_KEY)));

            this.getSUserMapper().insertSelective(su);

            if (category == UserTypeEnum.COMPANY.getValue()) {
                SUserInvite sui = new SUserInvite();
                sui.setCreateTime(d);
                long userId = su.getId();
                sui.setInviteCode(Md5PasswordEncoderUtils.getInvitationCode(userId + "", 6));
                sui.setInviteCodePriod(6);
                sui.setUserId(userId);
                this.getSUserInviteMapper().insert(sui);
            }

            BCompanyExample example = new BCompanyExample();
            example.createCriteria().andCompanyCodeEqualTo(surv.getCompanyCode());
            List<BCompany> cList = this.getBCompanyMapper().selectByExample(example);
            if (CollectionUtils.isNotEmpty(cList) && cList.size() > 0) {
                BCompany company = cList.get(0);
                // 添加公司用户关联数据
                BCompanyUser companyUser = new BCompanyUser();
                companyUser.setCompanyId(company.getId());
                companyUser.setUserId(su.getId());
                companyUser.setCreateTime(new Date());
                this.getBCompanyUserMapper().insertSelective(companyUser);

                // 企业用户注册完成 添加积分
                LOGGER.info("sign company user add scores by userId : {}, userType :{}.", su.getId(), category);
                BCompanyUserExample bCompanyUserExample = new BCompanyUserExample();
                bCompanyUserExample.createCriteria().andCompanyIdEqualTo(company.getId());
                List<BCompanyUser> list2 = this.getBCompanyUserMapper().selectByExample(bCompanyUserExample);
                if (list2.size() == 1) {
                    this.getBScoresTurnoverService().addDiscountScores(su.getId(), category);
                }
            }

            return r;
        } catch (Exception e) {
            LOGGER.error("sign company user ERROR : {}.", e);
            throw new BusinessException("添加企业用户异常");
        }
    }

    private Md5PasswordEncoder getmd5PasswordEncoder() {
        if (null == this.md5PasswordEncoder) {
            this.md5PasswordEncoder = new Md5PasswordEncoder();
        }
        return this.md5PasswordEncoder;
    }

    @Override
    public Map<String, Object> selectCompanyUser(PageVo page, CompanyUserVo companyUserVo) {
        LOGGER.info("selectCompanyUser params : {}, {}", page, companyUserVo);
        List<CompanyUserVo> cVos = new ArrayList<CompanyUserVo>();

        companyUserVo.setLimitStart(page.getStartIndex());
        companyUserVo.setLimitEnd(page.getPageSize());
        if (StringUtils.isNotBlank(page.getOrder())) {
            companyUserVo.setOrderByClause(page.getOrder());
        } else {
            companyUserVo.setOrderByClause("su.id DESC");
        }
        try {
            page.setTotalRecord(this.getCompanyUserManpper().countByExample(companyUserVo));
        } catch (Exception e) {
            LOGGER.error("select countByExample error : {}", e);
            throw new BusinessException("查询总记录数异常");
        }
        try {
            cVos = this.getCompanyUserManpper().selectCompanyUser(companyUserVo);
        } catch (Exception e) {
            LOGGER.error("select companyuserinfo error : {}", e);
            throw new BusinessException("查询企业用户信息错误");
        }
        Map<String, Object> map = new HashMap<String, Object>();

        map.put("companyUserInfo", cVos);
        map.put("page", page);
        return map;
    }

    @Override
    public List<BCompany> selectCompany() {

        List<BCompany> cList = new ArrayList<BCompany>();
        try {
            cList = this.getBCompanyMapper().selectByExample(new BCompanyExample());
        } catch (Exception e) {
            LOGGER.error("select ccompany error : {}", e);
            throw new BusinessException("查询公司信息错误");
        }
        return cList;
    }

    /*
     * 承运商列表
     *
     * (non-Javadoc)
     *
     * @see cn.huiyunche.admin.app.service.CompanyService#carrierList()
     */
    @Override
    public List<SUser> carrierList(Boolean truckType) throws Exception {
        List<SUser> users = new ArrayList<SUser>();
        // 查询个体司机
        List<SUser> users1 = this.getCarrierManpper().carrierList(truckType == null ? false : truckType);
        // 查询运输企业
        SUserExample example2 = new SUserExample();
        example2.createCriteria().andUserTypeEqualTo(UserTypeEnum.COMPANY.getValue());
        example2.setDistinct(true);
        List<SUser> users2 = this.getSUserMapper().selectByExample(example2);
        if (CollectionUtils.isNotEmpty(users1) && users1.size() > 0) {
            for (SUser user : users1) {
                users.add(user);
            }
        }
        if (CollectionUtils.isNotEmpty(users2) && users2.size() > 0) {
            for (SUser user : users2) {
                BCompanyUserExample bCompanyUserExample = new BCompanyUserExample();
                bCompanyUserExample.createCriteria().andUserIdEqualTo(user.getId());
                List<BCompanyUser> bCompanyUsers = this.getBCompanyUserMapper().selectByExample(bCompanyUserExample);
                if (CollectionUtils.isNotEmpty(bCompanyUsers)) {
                    Long companyId = bCompanyUsers.get(0).getCompanyId();
                    BCompany bCompany = this.getBCompanyMapper().selectByPrimaryKey(companyId);
                    if (null != bCompany) {
                        user.setRealName(bCompany.getCompanyName() + " - " + user.getRealName());
                        users.add(user);
                    }
                }
            }
        }
        return users;
    }

    @Override
    public BCompany getBCompanyByCurrentUser() {
        LOGGER.info("CompanyServiceImpl.getBCompanyByCurrentUser");
        UserShowVo userShowVo = this.getUserShowVo();
        if (null != userShowVo) {
            Long companyId = this.bCompanyUserService.getCompanyIdByUserId(userShowVo.getId());
            if (null != companyId) {
                return this.getBCompanyMapper().selectByPrimaryKey(companyId);
            }
        }
        return null;
    }

    /**
     * 根据类型 查询所有公司信息
     *
     * @param category
     * @return
     */
    @Override
    public List<BCompany> selectCompanyByCategory(String category) {
        try {
            LOGGER.info("select bcompany by category params category : {}.", category);
            BCompanyExample example = new BCompanyExample();
            example.createCriteria().andCompanyCategoryEqualTo(Integer.valueOf(category));
            return this.getBCompanyMapper().selectByExample(example);
        } catch (Exception e) {
            LOGGER.error("select bcompany by category params category : {}, ERROR : {}.", category, e);
            throw new BusinessException("根据类型查询公司信息异常");
        }
    }

    /**
     * 根据当前用户 查询公司名称
     *
     * @return
     */
    @Override
    public String getNameBycurrentUser() {
        LOGGER.info("select company name by current user.");
        try {
            // 查询当前用户
            UserShowVo userShowVo = this.getUserShowVo();
            LOGGER.info("select current user userShowVo : {}.", JSON.toJSONString(userShowVo));
            if (null == userShowVo) {
                LOGGER.info("select current user is not exist userShowVo : {}.", JSON.toJSONString(userShowVo));
                throw new BusinessException("当前登录账户不存在");
            }
            BCompanyExample example = new BCompanyExample();
            example.createCriteria().andCompanyCodeEqualTo(userShowVo.getCompanycode());
            List<BCompany> bCompany = this.getBCompanyMapper().selectByExample(example);
            if (!Collections.isEmpty(bCompany)) {
                return bCompany.get(0).getCompanyName();
            }
        } catch (Exception e) {
            LOGGER.error("select company name by current user error : {}.", e);
            throw new BusinessException("根据当前用户查询公司名称异常");
        }
        return null;
    }

    /**
     * 根据当前用户 查询用户登录后信息
     *
     * @return
     */
    @Override
    public Map<String, Object> getSCompanyUserInfo() {
        Map<String, Object> map = new HashMap<String, Object>();
        // 查询当前用户
        UserShowVo userShowVo = this.getUserShowVo();
        LOGGER.info("select current user userShowVo : {}.", JSON.toJSONString(userShowVo));
        if (null == userShowVo) {
            LOGGER.info("select current user is not exist userShowVo : {}.", JSON.toJSONString(userShowVo));
            throw new BusinessException("当前登录账户不存在");
        }
        Long userId = userShowVo.getId();
        Integer userType = userShowVo.getUserType();
        map.put("userName", userShowVo.getRealName());

        LOGGER.info("select scompany user info by currentuser");
        try {
            BCompanyExample example = new BCompanyExample();
            if (null != userShowVo.getCompanycode()) {
                example.createCriteria().andCompanyCodeEqualTo(userShowVo.getCompanycode());
            }
            List<BCompany> bCompanies = this.getBCompanyMapper().selectByExample(example);
            if (!Collections.isEmpty(bCompanies) && bCompanies.get(0).getCompanyName() != "") {
                String companyName = bCompanies.get(0).getCompanyName();
                map.put("companyName", companyName);
            } else {
                map.put("companyName", null);
            }
            // 查询公司 最后一月的账单
            CBill lastMonthBill = this.getCAccntBillService().getLastMonthBill(userId, userType);
            Boolean bool = this.bCompanyUserService.isBaseUser();
            if (lastMonthBill != null) {
                BigDecimal amount = lastMonthBill.getAmount();
                if (bool) {
                    map.put("amount", amount);
                } else {
                    map.put("amount", 0);
                }
                Calendar ca = Calendar.getInstance();
                ca.setTime(lastMonthBill.getBeginDate());
                int year = ca.get(Calendar.YEAR);
                int month = ca.get(Calendar.MONTH) + 1 + 1; // 9-25至10-25账单 算10月账单
                map.put("month", month + "月");
                map.put("settlementDate", year + "-" + month + "-25");
            } else {
                map.put("amount", null);
                map.put("month", null);
                Calendar ca = Calendar.getInstance();
                int year = ca.get(Calendar.YEAR);
                int month = ca.get(Calendar.MONTH) + 1;
                int date = ca.get(Calendar.DATE);
                if (date >= 26) {
                    month += 1;
                }
                map.put("settlementDate", year + "-" + month + "-25");
            }

            // 查询该公司 当前积分余额
            BScores userScores = this.getBScoresService().getUserScores(userId, userType);
            if (userScores != null) {
                BigDecimal scores = userScores.getScores();
                if (bool) {
                    map.put("scores", scores);
                } else {
                    map.put("scores", 0);
                }
            } else {
                map.put("scores", null);
            }
        } catch (Exception e) {
            LOGGER.error("select scompany user info by currentuser error.", e);
            throw new BusinessException("查询托运企业的登录信息异常");
        }
        return map;
    }

}